home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Frameworks / Grant's CGI Framework 1.0b12 / Util / main.c < prev    next >
Text File  |  1995-12-09  |  7KB  |  327 lines

  1. /*****
  2.  *
  3.  *    Grant's CGI Shell (Common Grant Interface :-)
  4.  *        http://arpp1.carleton.ca/grant/mac/grantscgi.html
  5.  *
  6.  *    main.c
  7.  *
  8.  *    by Grant Neufeld
  9.  *
  10.  *    Copyright ©1995 by Grant Neufeld
  11.  *
  12.  *    http://arpp1.carleton.ca/grant/
  13.  *    gneufeld@ccs.carleton.ca
  14.  *    grant@acm.org
  15.  *
  16.  *    This source may be freely used as long as the copyright notice is kept in the source.
  17.  *    I ask that you let me know of any enhancements (read: bug fixes) to this code.
  18.  *    I would also like copies of (or discounts on) anything you produce using this code, please.
  19.  *
  20.  *****/
  21.  
  22. #define __MainSegment__    1
  23.  
  24. #include "MyConfiguration.h"
  25.  
  26. #include <string.h>
  27. #include <Threads.h>
  28. #if __profile__ && __MWERKS__
  29. #include <Profiler.h>
  30. #endif
  31.  
  32. #include "compiler_stuff.h"
  33. #include "constants.h"
  34. #include "globals.h"
  35.  
  36. #include "DebugUtil.h"
  37. #include "ErrorUtil.h"
  38. #include "EventUtil.h"
  39. #include "MemoryUtil.h"
  40. #include "MenuFunc.h"
  41. #include "Quit.h"
  42. #include "Startup.h"
  43.  
  44.  
  45. /***  LOCAL VARIABLES  ***/
  46.  
  47. static    RgnHandle    vTheMouseRgn;
  48.     
  49.  
  50. /***  LOCAL PROTOTYPES ***/
  51.  
  52. static    void    mainEventLoop        ( void );
  53. static    void    startupToolbox        ( void );
  54. static    Boolean    initAppMemory        ( void );
  55. static    OSErr    initStackGrow        ( Size );
  56.         
  57.  
  58. /***  FUNCTIONS  ***/
  59.  
  60. /* Application entry point. */
  61. void
  62. main ( void )
  63. {
  64.     /* Application is not set to quit */
  65.     gQuit = false;
  66.     
  67.     /* Included here because of InitWindows() allocation of non-relocatable blocks.
  68.         This needs to be done before any other code segments are loaded.
  69.         IM:Processes 7-5 */
  70.     /* initialize standard toolbox managers */
  71.     startupToolbox ();
  72.     
  73.     /* Included here because of MoreMasters() allocation of non-relocatable blocks.
  74.         This needs to be done before any other code segments are loaded.
  75.         IM:Processes 7-5 */
  76.     if ( !( initAppMemory () ) )
  77.     {
  78.         /* inform user of insufficient memory */
  79.         ErrorStartup    ( kerrStartupMemory );
  80.         ExitToShell        ();
  81.     }
  82.     
  83.     #if __profile__ && __MWERKS__
  84.     gProfileOn = !( ProfilerInit ( collectDetailed, bestTimeBase, 20, 5 ) );
  85.     #endif
  86.     
  87.     StartupApplication    ();
  88.     
  89.     /* main loop for handling system and user events */
  90.     mainEventLoop ();
  91.     
  92.     #if __profile__ && __MWERKS__
  93.     if ( gProfileOn )
  94.     {
  95.         ProfilerDump("\p" kProfileNameStr "-" kProcessorString ".prof");
  96.         ProfilerTerm();
  97.     }
  98.     #endif
  99.     
  100.     ExitToShell ();
  101. } /* main */
  102.  
  103.  
  104. /* main loop for handling system and user events.
  105.     Continuously loop until application is set to quit. */
  106. static void
  107. mainEventLoop ( void )
  108. {
  109.     #if !(kCompileWithQuitOnLowMemory)
  110.     OSErr            theErr;
  111.     #endif
  112.     Boolean            eventResult;
  113.     EventRecord        event;
  114.     short            loopCounter;
  115.     
  116.     while ( !gQuit )
  117.     {
  118.         #if !(kCompileWithQuitOnLowMemory)
  119.         /* if app doesn't quit on low memory, may need to recover emrgncy mem */
  120.         /* IM-Memory: 1-48 */
  121.         if ( !IsEmergencyMemAvail() )
  122.         {
  123.             theErr = RecoverEmergencyMemory ();
  124.             
  125.             if ( theErr != noErr )
  126.             {
  127.                 gQuit = true;
  128.             }
  129.         }
  130.         #endif
  131.         
  132.         #if kCompileWithThreadsOptional
  133.         if ( gHasThreadMgr )
  134.         #endif
  135.         {
  136.             /* Yield more often if there are any sub-threads. The 'more often'
  137.                 depends on how many sub-threads there are */
  138.             if ( gThreadTotal > 1 )
  139.             {
  140.                 for ( loopCounter = nil; loopCounter < gThreadTotal; loopCounter++ )
  141.                 {
  142.                     YieldToAnyThread ();
  143.                 }
  144.             }
  145.             else
  146.             {
  147.                 /* just yield once if there are no sub-threads, or only one */
  148.                 YieldToAnyThread ();
  149.             }
  150.         }
  151.         
  152.         if ( !gQuit )
  153.         {
  154.             /* wait until the next event */
  155.             eventResult = WaitNextEvent ( everyEvent, &event, gSleepTicks, nil );
  156.             
  157.             if ( eventResult )
  158.             {
  159.                 /* if there is an event other than null */
  160.                 /* clean up the menus */
  161.                 adjustMenus ();
  162.                 
  163.                 /* figure out which event and process it */
  164.                 switch ( event.what ) 
  165.                 {
  166.                     case kHighLevelEvent:
  167.                         doHighLevelEvent ( &event );
  168.                         break;
  169.                     
  170.                     #if kCompileWithForeground
  171.                     
  172.                     case mouseDown:    
  173.                         doMouseDown ( &event );
  174.                         break;
  175.                     
  176.                     case mouseUp:
  177.                         doMouseUp ( &event );
  178.                         break;
  179.                     
  180.                     case keyDown:
  181.                         doKeyDown ( &event );
  182.                         break;
  183.                     
  184.                     case autoKey:
  185.                         doAutoKey ( &event );
  186.                         break;
  187.                     
  188.                     /* typically not sent to the application. IM-MTE: 2-28 */
  189.                     case keyUp:
  190.                         doKeyUp ( &event );
  191.                         break;
  192.                     
  193.                     case activateEvt:
  194.                         doActivateEvent ( &event );
  195.                         break;
  196.         
  197.                     case updateEvt:
  198.                         doUpdateEvent ( &event );
  199.                         break;
  200.                     
  201.                     /* suspend or resume */
  202.                     case osEvt:
  203.                         doOsEvt ( &event );
  204.                         break;
  205.                     
  206.                     /* disk inserted */
  207.                     case diskEvt:
  208.                         doDiskEvt ( &event );
  209.                         break;
  210.                     
  211.                     #endif    /* kCompileWithForeground */
  212.                     
  213.                     default:
  214.                         doIdle ( &event );
  215.                         break;
  216.                 }
  217.             }
  218.             else
  219.             {
  220.                 /* not a handled event, or event is null */
  221.                 doIdle ( &event );
  222.             }
  223.         }
  224.         
  225.         if ( gQuit )
  226.         {
  227.             QuitPrepare ( true );
  228.         }
  229.     }
  230. } /* mainEventLoop */
  231.  
  232.  
  233. /***  INITIALIZATION  ***/
  234. #pragma mark -
  235.  
  236. /* initialize standard toolbox managers */
  237. static void
  238. startupToolbox ( void )
  239. {
  240.     InitGraf    ( (Ptr)(&qd.thePort) );    /* InitGraf must be first */
  241.     
  242.     #if kCompileWithForeground
  243.     /* initialize interface managers */
  244.     
  245.     InitFonts    ();
  246.     InitWindows    ();
  247.     InitMenus    ();                        /* InitMenus must be after InitWindows */
  248.     FlushEvents    ( everyEvent, nil );    /* IM-MTE: 2-93 */
  249.     TEInit        ();
  250.     InitDialogs    ( nil );                /* InitDialogs must be after TEInit */
  251.     InitCursor    ();
  252.     
  253.     #endif
  254. } /* startupToolbox */
  255.  
  256.  
  257. /* Return true if memory initialization was successful. */
  258. static Boolean
  259. initAppMemory ( void )
  260. {
  261.     short         mstrPtrsAllocated;
  262.     long         freeMemAvail;
  263.     Boolean        success;
  264.     Handle        sacrificeHandle;
  265.     
  266.     #if !(kCompileWithForeground)
  267.     /* Background only apps get a default 8K stack instead of 24K.
  268.         Increase stack size if set to background only - just to be on the safe side */
  269.     success = ( initStackGrow(16384) == noErr );
  270.     #endif
  271.     
  272.     /* NOTE: MaxApplZone must be called before any memory is allocated by threads
  273.         other than the main (application) thread. */
  274.     /* maximize available memory in the application heap */
  275.     MaxApplZone ();
  276.     
  277.     freeMemAvail = FreeMem ();
  278.     
  279.     if ( freeMemAvail < kMinSegSize )
  280.     {
  281.         /* not enough memory for application to run */
  282.         success = false;
  283.     }
  284.     else
  285.     {
  286.         /* to avoid memory fragmentation, allocate master pointers at bottom of heap */
  287.         for ( mstrPtrsAllocated = 0; mstrPtrsAllocated < kMoreMasterCalls; mstrPtrsAllocated++ )
  288.         {
  289.             MoreMasters ();
  290.         }
  291.         
  292.         success = InitializeEmergencyMemory ( nil );
  293.     }
  294.     
  295.     /* Allocate a 1K memory block, force it to the top of the heap, and lock it.
  296.        This block is not used for anything - it is put at the top of the heap
  297.        as a sacrifice because sometimes MacSLIP's VBL task trashes the end of 
  298.        the heap.
  299.        from "NewsWatcher" 'newswatcher.c' */
  300.     sacrificeHandle = MyNewHandle ( 1024, nil );
  301.     if ( sacrificeHandle != nil )
  302.     {
  303.         HLockHi ( sacrificeHandle );
  304.     }
  305.     
  306.     return success;
  307. } /* initAppMemory */
  308.  
  309.  
  310. /*  */
  311. static OSErr
  312. initStackGrow ( Size increaseSize )
  313. {
  314.     OSErr theErr;
  315.     
  316.     my_assert ( (increaseSize % 1024) == nil, "\pinitStackGrow: size is not multiple of 1024" );
  317.     
  318.     /* Increase the stack size by lowering the heap limit. */
  319.     SetApplLimit ( (Ptr)(((unsigned long)GetApplLimit()) - increaseSize) );
  320.     theErr = MemError ();
  321.     
  322.     return theErr;
  323. } /* initStackGrow */
  324.  
  325.  
  326. /*** EOF ***/
  327.